package com.jun.seckill_by_jun.controller;

import com.jun.seckill_by_jun.domain.OrderInfo;
import com.jun.seckill_by_jun.domain.SeckillOrder;
import com.jun.seckill_by_jun.domain.SeckillUser;
import com.jun.seckill_by_jun.rabbitmq.MQReceiver;
import com.jun.seckill_by_jun.rabbitmq.MQSender;
import com.jun.seckill_by_jun.rabbitmq.SeckillMessage;
import com.jun.seckill_by_jun.redis.GoodsKey;
import com.jun.seckill_by_jun.redis.RedisService;
import com.jun.seckill_by_jun.result.CodeMsg;
import com.jun.seckill_by_jun.result.Result;
import com.jun.seckill_by_jun.service.GoodsService;
import com.jun.seckill_by_jun.service.OrderService;
import com.jun.seckill_by_jun.service.SeckillService;
import com.jun.seckill_by_jun.vo.GoodsVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/seckill")
public class SeckillController implements InitializingBean {

    @Autowired
    private OrderService orderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private SeckillService seckillService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MQSender mqSender;

    @Autowired
    private MQReceiver mqReceiver;

    Map<Long,Boolean> flag = new HashMap<>();

    @RequestMapping("/do_seckill")
    @ResponseBody
    public Result<OrderInfo> doSeckill(Model model, SeckillUser user,
                                            @RequestParam("goodsId")long goodsId){
        if(user == null){
            return Result.error(CodeMsg.SESSION_ERROR);
        }
//        model.addAttribute("user",user);
        //判断库存是否足够
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        boolean over = flag.get(goodsId);
        if(over){
            return Result.error(CodeMsg.SECKILL_OVER);
        }
        long stock = redisService.decr(GoodsKey.getGoodsStock,""+goods.getId());
        if(stock <0){
//            model.addAttribute("errmsg", CodeMsg.SECKILL_OVER);
            flag.put(goodsId,true);
            return Result.error(CodeMsg.SECKILL_OVER);
        }
        //判断是否重复秒杀
        SeckillOrder order = orderService.getOrderByUserIdGoodsId(user.getId(), goodsId);
        if(order != null){
//            model.addAttribute("errmsg", CodeMsg.REPEATE_SECKILL);
            return Result.error(CodeMsg.REPEATE_SECKILL);
        }
        //写入队列
        SeckillMessage message = new SeckillMessage();
        message.setUser(user);
        message.setGoodsId(goodsId);
        mqSender.send(message);
        //写入秒杀订单：1.减库存 2.下订单 3.写入秒杀订单
        OrderInfo orderInfo =  seckillService.seckill(user,goods);
//        model.addAttribute("orderInfo",orderInfo);
//        model.addAttribute("goods",goods);

        return Result.success(orderInfo);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVo> goodsVos = goodsService.listGoodVo();
        if(goodsVos == null){
            return;
        }else{
            for(GoodsVo goods : goodsVos){
                redisService.set(GoodsKey.getGoodsStock,""+goods.getId(),goods.getStockCount());
                flag.put(goods.getId(),false);
            }

        }
    }

    /**
     * orderId：成功
     * -1：秒杀失败
     * 0： 排队中
     */
    @RequestMapping(value = "/result",method = RequestMethod.GET)
    @ResponseBody
    public Result<Long> seckillResult(SeckillUser user,
                                      @RequestParam("goodsId") long goodsId){
        if(user == null){
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        long orderId =  seckillService.getSeckillResult(user.getId(),goodsId);
        return Result.success(orderId);
    }
}
